<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>SignalR JWT Sample</title>
</head>
<body>
    <div id="log">

    </div>
</body>
</html>
<script type="text/javascript" src="lib/signalr-client/signalr.js"></script>
<script>

    function createLog(clientId) {
        var log = document.getElementById('log');
        var ul =  document.createElement('ul');
        ul.id = 'log' + clientId;
        log.appendChild(ul);
    }

    function appendLog(clientId, entry) {
        var listId = document.getElementById('log' + clientId);
        if (listId.children.length > 11) {
            listId.removeChild(listId.children[1]);
        }
        var child = document.createElement('li');
        child.innerText = entry;
        listId.appendChild(child);
    }

    function get(url) {
        return new Promise((resolve, reject) => {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', url, true);
            xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
            xhr.send();
            xhr.onload = () => {
                if (xhr.status >= 200 && xhr.status < 300) {
                    resolve(xhr.response || xhr.responseText);
                }
                else {
                    reject(new Error(xhr.statusText));
                }
            };

            xhr.onerror = () => {
                reject(new Error(xhr.statusText));
            }
        });
    }

    var tokens = {};

    function refreshToken(clientId) {
        var tokenUrl = 'http://' + document.location.host + '/generatetoken?user=' + clientId;
        return get(tokenUrl)
            .then(function (token) {
                tokens[clientId] = token;
            });
    }

    function runConnection(clientId, transportType) {
        var connection;

        refreshToken(clientId)
            .then(function () {
                var options = {
                    transport: transportType,
                    accessTokenFactory: function () { return tokens[clientId]; }
                };
                connection = new signalR.HubConnectionBuilder()
                    .withUrl("/broadcast", options)
                    .configureLogging(signalR.LogLevel.Information)
                    .build();

                connection.on('Message', function (from, message) {
                    appendLog(clientId, from + ': ' + message);
                });
                return connection.start();
            })
            .then(function () {
                appendLog(clientId, 'user ' + clientId + ' connected');
                setInterval(function () {
                    appendLog(clientId, 'Refreshing token');
                    refreshToken(clientId);
                }, 20000);
                setTimeout(function sendMessage() {
                    connection.send('broadcast', clientId, 'Hello at ' + new Date().toLocaleString());
                    var timeout = 2000 + Math.random() * 4000;
                    setTimeout(sendMessage, timeout);
                })
            })
            .catch(function (e) {
                appendLog(clientId, 'Could not start connection');
            });
    }

    [signalR.HttpTransportType.WebSockets, signalR.HttpTransportType.ServerSentEvents, signalR.HttpTransportType.LongPolling].forEach(function(transportType) {
        var clientId = 'browser ' + signalR.HttpTransportType[transportType];
        createLog(clientId);
        appendLog(clientId, 'Log for user: ' + clientId);
        runConnection(clientId, transportType);
    });

</script>
